import Vue from "vue";
import Vuex from "vuex";
import { watchModeType } from "@/global";
import router from "@/router";
import { login, info } from "@/api/user";
import { getAllFileType, getUsage } from "@/api/file";
import { Loading, Message } from "element-ui";

Vue.use(Vuex);

const loading = Loading.service;

const getDefaultWorld = function() {
  return {
    userInfo: {
      id: null,
      name: null,
      usage: null,
      role: {
        roleName: null,
        roleDesc: null,
        diskSize: null
      },
      uploadQueue: [],
      downloadQueue: [],
      transHistory: [],
      downloadPath: null
    },
    token: null,
    fileType: null,
    watchMode: watchModeType.grid
  };
};

export default new Vuex.Store({
  state: {
    world: {
      userInfo: {
        id: null,
        name: null,
        usage: null,
        role: {
          roleName: null,
          roleDesc: null,
          diskSize: null
        },
        uploadQueue: [],
        downloadQueue: [],
        transHistory: [],
        downloadPath: null
      },
      token: null,
      fileType: null,
      watchMode: watchModeType.grid
    }
  },
  getters: {
    userInfo: state => state.world.userInfo,
    fileType: state => state.world.fileType,
    watchMode: state => state.world.watchMode,
    token: state => state.world.token,
    world: state => state.world,
    uploadQueue: state => state.world.userInfo.uploadQueue,
    downloadQueue: state => state.world.userInfo.downloadQueue,
    transHistory: state => state.world.userInfo.transHistory
  },
  mutations: {
    RESET_STATE: state => {
      Object.assign(state, getDefaultWorld());
      localStorage.clear();
    },
    SET_WATCH_MODE: (state, mode) => {
      state.world.watchMode = mode;
    },
    SET_FILE_TYPE: (state, fileType) => {
      state.world.fileType = fileType;
    },
    SET_TOKEN: (state, token) => {
      state.world.token = token;
    },
    SET_USER: (state, user) => {
      const { id, name } = user;
      state.world.userInfo.id = id;
      state.world.userInfo.name = name;
    },
    SET_ROLE: (state, role) => {
      const { roleName, roleDesc, diskSize } = role;
      let stateRole = state.world.userInfo.role;
      stateRole.roleName = roleName;
      stateRole.roleDesc = roleDesc;
      stateRole.diskSize = diskSize;
    },
    SET_USAGE: (state, usage) => {
      state.world.userInfo.usage = usage;
    },
    OFFER_UPLOAD_QUEUE: (state, element) => {
      state.world.userInfo.uploadQueue.push(element);
    },
    UPDATE_UPLOAD_QUEUE_FIRST_ELEMENT_UPLOADED_CHUNK_NUM: (state, num) =>
      (state.world.userInfo.uploadQueue[0].uploadedChunkNum += num),

    UPDATE_DOWNLOAD_QUEUE_FIRST_ELEMENT_UPLOADED_DOWNLOADED: (state, num) =>
      (state.world.userInfo.downloadQueue[0].downloaded += num),

    SET_DOWNLOAD_FIRST_ELEMENT_FILE_SIZE: (state, fileSize) =>
      (state.world.userInfo.downloadQueue[0].fileSize = fileSize),

    OFFER_DOWNLOAD_QUEUE: (state, e) =>
      state.world.userInfo.downloadQueue.push(e),

    CLEAR_UPLOAD_QUEUE: state => {
      state.world.userInfo.uploadQueue = [];
    },

    CLEAR_DOWNLOAD_QUEUE: state => {
      state.world.userInfo.downloadQueue = [];
    },

    CLEAR_TRANS_HISTORY: state => {
      state.world.userInfo.transHistory = [];
    },

    DELETE_ELEMENT_FROM_UPLOAD_QUEUE: (state, e) => {
      const i = state.world.userInfo.uploadQueue.indexOf(e);
      state.world.userInfo.uploadQueue.splice(i, 1);
    },

    DELETE_ELEMENT_FROM_DOWNLOAD_QUEUE: (state, e) => {
      const i = state.world.userInfo.downloadQueue.indexOf(e);
      state.world.userInfo.downloadQueue.splice(i, 1);
    },

    OFFER_TRANS_HISTORY: (state, e) =>
      state.world.userInfo.transHistory.push(e),

    DELETE_ELEMENT_FROM_TRANS_HISTORY: (state, e) => {
      const i = state.world.userInfo.transHistory.indexOf(e);
      state.world.userInfo.transHistory.splice(i, 1);
    }
  },
  actions: {
    offerUploadQueue(
      { commit },
      { filepath, chunkNum, uploadedChunkNum = 0, parentId, filename }
    ) {
      commit("OFFER_UPLOAD_QUEUE", {
        filepath,
        chunkNum,
        uploadedChunkNum,
        parentId,
        filename
      });
    },
    offerDownloadQueue(
      { commit },
      { fileId, filename, downloaded = 0, fileSize = -1 }
    ) {
      commit("OFFER_DOWNLOAD_QUEUE", {
        fileId,
        filename,
        downloaded,
        fileSize
      });
    },
    clearUploadQueue({ commit }) {
      commit("CLEAR_UPLOAD_QUEUE");
    },
    clearDownloadQueue({ commit }) {
      commit("CLEAR_DOWNLOAD_QUEUE");
    },
    deleteUploadQueueElement({ commit }, e) {
      commit("DELETE_ELEMENT_FROM_UPLOAD_QUEUE", e);
    },
    deleteHistoryElement({ commit }, e) {
      commit("DELETE_ELEMENT_FROM_TRANS_HISTORY", e);
    },
    deleteDownloadQueueElement({ commit }, e) {
      commit("DELETE_ELEMENT_FROM_DOWNLOAD_QUEUE", e);
    },
    setDownloadQueue(downloadQueue) {
      this.state.world.userInfo.downloadQueue = downloadQueue;
    },
    clearHistory({ commit }) {
      commit("CLEAR_TRANS_HISTORY");
    },
    login({ commit }, val) {
      loading();
      const { username, passwd } = val;
      login({ userName: username, password: passwd })
        .then(res => {
          const token = res.data;
          commit("SET_TOKEN", token);
          info(token).then(res => {
            const data = res.data;
            let role = data.role;
            commit("SET_USER", { id: data.id, name: data.userName });
            commit("SET_ROLE", {
              ...role
            });
            getAllFileType().then(res => {
              let obj = {};
              //将typeId作为键值对的key，方便id和类型一一对应
              res.data.forEach(t => {
                obj[t.id] = { typeSuffix: t.typeSuffix, typeDesc: t.typeDesc };
              });
              commit("SET_FILE_TYPE", obj);
            });
            getUsage().then(res => {
              commit("SET_USAGE", res.data);
              localStorage.setItem("world", JSON.stringify(this.state.world));
              router.replace("/").then(() => loading().close());
            });
          });
        })
        .catch(msg => {
          Message({
            message: msg,
            type: "error",
            duration: 5 * 1000
          });
          loading().close();
        });
    },
    logout({ commit }) {
      loading();
      commit("RESET_STATE");
      location.reload();
      router.replace({ path: "/login" }).then(() => loading().close());
    },
    setListMode({ commit }) {
      commit("SET_WATCH_MODE", watchModeType.list);
    },
    setGridMode({ commit }) {
      commit("SET_WATCH_MODE", watchModeType.grid);
    }
  }
});
